const proto_man = require("proto_man");
const proto_tools = require("proto_tools");

const websocket = {
    sock: null,
    services_handler: {},
    proto_type: 0,
    is_connected: false,

    _on_opened: function (event) {
        console.log(`ws connect server success`);
        this.is_connected = true;
    },

    _on_recv_data: function (event) {
        let str_or_buf = event.data;
        if (!this.services_handler) return;
        let cmd = proto_man.decode_cmd(this.proto_type, str_or_buf);
        if (!cmd) return;

        let stype = cmd[0];
        console.log(`onRecvMsg`, this.services_handler[stype]);

        if (this.services_handler[stype]) {
            this.services_handler[stype](cmd[0], cmd[1], cmd[2]);
        }
    },

    _on_socket_close: function (event) {
        if (this.sock) {
            this.close();
        }
    },

    _on_socket_err: function (event) {
        this.close();
    },

    connect: function (url, proto_type) {
        this.sock = new WebSocket(url);
        this.sock.binaryType = `arraybuffer`;

        this.sock.onopen = this._on_opened.bind(this);
        this.sock.onmessage = this._on_recv_data.bind(this);
        this.sock.onclose = this._on_socket_close.bind(this);
        this.sock.onerror = this._on_socket_err.bind(this);
        this.proto_type = proto_type;
    },

    send: function (body) {
        if (this.sock) {
            this.sock.send(body);
        }
    },

    send_cmd: function (stype, ctype, body) {
        if (!this.sock || !this.is_connected) {
            return;
        }
        let buf = proto_man.encode_cmd(this.proto_type, stype, ctype, body);
        this.sock.send(buf);
    },

    send_encode_cmd(cmd){
        if (!this.sock || !this.is_connected) {
            return;
        }
        proto_tools.write_prototype_inbuf(cmd, this.proto_type);
        let buf = cmd.buffer;
        this.sock.send(buf);
    },

    close: function () {
        this.is_connected = false;
        console.log(`ws close!`);
        if (this.sock !== null) {
            this.sock.close();
            this.sock = null;
        }
    },

    register_services_handler: function (services_handler) {
        this.services_handler = services_handler;
    }
}

// websocket.connect("ws://127.0.0.1:6081/ws", proto_man.PROTO_JSON);
websocket.connect("ws://127.0.0.1:6081/ws", proto_man.PROTO_BUF);

module.exports = websocket;